home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / PACKET / CBBS60SO.ZIP / MBFWD.C < prev    next >
Text File  |  1989-02-20  |  21KB  |  980 lines

  1.  
  2. /*
  3.  *  MBFWD.C - 1/31/89 - Autoforwarding.
  4.  *
  5.  *  The target port mode is set to idle if not connected,
  6.  *  set to remote if connected. It is set to disconnect or timeout
  7.  *  by getdat(), but this is checked and fixed up in getln().
  8.  *
  9.  *  All port input is through getln().
  10.  *  All file input is through nxtin().
  11.  */
  12.  
  13. #include "mb.h"
  14.  
  15. #define deepmax    5     /* Max nesting depth of indirection in fwd.mb */
  16.  
  17. #define fw_one     0x01  /* Forward to only one MailBox, given in fcall*/
  18. #define fw_anytime 0x02  /* Ignore the times in the "G" item           */
  19. #define fw_abort   0x04  /* Abort forwarding as soon as possible       */
  20. #define fw_tried   0x08  /* Attempted to forward to this MailBox       */
  21. #define fw_tiout   0x10  /* Forward timeout flag                       */
  22. #define fw_forced  0x20  /* Forced forward flag                        */
  23. #define fw_pass    0x40  /* Bypass forward sub file                    */
  24.  
  25. char  *script;           /* Pointer to where the connect script is     */
  26.  
  27. byte  fopts;             /* Options, see defines above.                */
  28. char  fwdtyp;
  29. char  *fwdfile;          /* The file name of fwd.mb root file          */
  30. FILE  *ifl[deepmax];     /* File variables for fwd.mb                  */
  31. short deep;              /* Current depth within fwd.mb                */
  32. char  path[80];          /* "G" item saved here, for logging           */
  33. char  fcall[10];         /* Call of the MailBox to forward to          */
  34.  
  35. /*
  36.  *  YF command: change the name of the forwarding root file.
  37.  */
  38.  
  39. newfwd()
  40. {
  41.   if (*port->fld[1])
  42.   {
  43.     free(fwdfile);
  44.     fwdfile = strdup(port->fld[1]);
  45.   }
  46.   sprintf(tmp->scr, "is %s\n", fwdfile);
  47.   outstr(tmp->scr);
  48. }
  49.  
  50. /*
  51.  *  Add a call to the list of BBS that have messages to be forwarded to them.
  52.  */
  53.  
  54. addbfwd(cp)
  55. char *cp;
  56. {
  57.   register short i;
  58.   register char *lp;
  59.  
  60.   for (i = 0, lp = bfwd; i < bfwdn; i++, lp += ln_call)
  61.     if (matchn(cp, lp, ln_call)) return;
  62.  
  63.   if (bfwdn < bfwdm) { strncpy(lp, cp, ln_call); bfwdn++; }
  64. }
  65.  
  66. /*
  67.  *  Add a call to the list of users that have unread messges.
  68.  */
  69.  
  70. addufwd(cp)
  71. char *cp;
  72. {
  73.   register short i;
  74.   register char *lp;
  75.  
  76.   for (i = 0, lp = ufwd; i < ufwdn; i++, lp += ln_call)
  77.     if (matchn(cp, lp, ln_call)) return;
  78.  
  79.   if (ufwdn < ufwdm) { strncpy(lp, cp, ln_call); ufwdn++; }
  80. }
  81.  
  82. /*
  83.  *  Check if a call has a message to be forwarded to it.
  84.  */
  85.  
  86. findfwd(cp, lp, n)
  87. char *cp, *lp;
  88. short n;
  89. {
  90.   register short i;
  91.  
  92.   for (i = 0; i < n; i++, lp += ln_call) if (wcm(cp, lp)) return true;
  93.   return false;
  94. }
  95.  
  96. /*
  97.  *  Add the info from one message header to the lists of calls
  98.  *  of stations that have messages to be forwarded to them.
  99.  *
  100.  *  ufwd - Calls to put in beacon line.
  101.  *  bfwd - Calls that have message TO or AT.
  102.  */
  103.  
  104. addfwd()
  105. {
  106.   register short i;
  107.   char *p, hcall[6];
  108.  
  109.   if (!(port->mmhs->stat & (m_busy | m_kill | m_read | m_fwd | m_hold)))
  110.   {
  111.     if (*port->mmhs->bbs is ' ')
  112.     {
  113.       addufwd(port->mmhs->to);
  114.       addbfwd(port->mmhs->to);
  115.     }
  116.     else
  117.     {
  118.       if (port->mmhs->ext is 1)
  119.       {
  120.         for (i = 0; i < port->mmhs->count; i++) if (port->mmhs->flag[i])
  121.           addbfwd(port->mmhs->call[i]);
  122.       }
  123.       else
  124.       {
  125.         if (matchn(port->mmhs->bbs, cport->user->call, ln_call))
  126.           addufwd(port->mmhs->to);
  127.         else addbfwd(port->mmhs->bbs);
  128.         if (port->mmhs->ext is 2)
  129.         {
  130.           p = port->mmhs->call[0];
  131.           while((p = strchr(p, '.')) isnt NULL)
  132.           {
  133.             p++;
  134.             fill(hcall, ' ', ln_call);
  135.             pcall(hcall, p);
  136.             addbfwd(hcall);
  137.           }
  138.         }
  139.       }
  140.     }
  141.   }
  142. }
  143.  
  144. /*
  145.  *  Build the two lists of calls of stations that have
  146.  *  messages to be forwarded to them.
  147.  */
  148.  
  149. bldfwd()
  150. {
  151.   register word  h;
  152.  
  153.   ufwdn = 0;
  154.   bfwdn = 0;
  155.   read_rec(mfl, 0, (char *)mfhs);
  156.   for (h = mfhs->last; h; h--)
  157.   {
  158.     read_rec(mfl, h, (char *)port->mmhs);
  159.     if (!(port->mmhs->stat & (m_busy | m_kill | m_read | m_fwd | m_hold)))
  160.     addfwd();
  161.   }
  162. }
  163.  
  164. /*
  165.  *  Return true if the current time is within
  166.  *  the time window for forwarding to this MailBox.
  167.  */
  168.  
  169. chktime()
  170. {
  171.   register short c, en, st;
  172.  
  173.   if (fopts & fw_anytime) return true;
  174.   curtim();
  175.   st = 10 * (int)(cport->line[2] - '0') + (int)(cport->line[3] - '0');
  176.   en = 10 * (int)(cport->line[4] - '0') + (int)(cport->line[5] - '0');
  177.   c  = 10 * (int)(l_time[0] - '0') + (int)(l_time[1] - '0');
  178.   if (st <= en) return ((c >= st) and (c <= en));
  179.   return ((c >= st) or (c <= en));
  180. }
  181.  
  182. /*
  183.  *  Check if it is ok to forward using this list.
  184.  *  Return a pointer to the port to use for forwarding, or NULL.
  185.  */
  186.  
  187. PORTS *chkfwd()
  188. {
  189.   register PORTS *p;
  190.  
  191.   if (fopts & fw_one)
  192.   if (!match (fcall, cport->fld[1]))       { passlst(); return NULL; }
  193.   if (!chktime())                          { passlst(); return NULL; }
  194.   if ((p = findport(cport->opt2)) is NULL) { passlst(); return NULL; }
  195.   if (!(p->flags & p_dofwd))               { passlst(); return NULL; }
  196.   if (fopts & fw_abort)                    { passlst(); return NULL; }
  197.   p->mode = idle;
  198.   return p;
  199. }
  200.  
  201. /*
  202.  *  Check if a disconnect happened.
  203.  */
  204.  
  205. chkdis()
  206. {
  207.   if (instat()) if (getdat()) if (isdis(port->line))
  208.     { cmdtnc(); port->mode = idle; return true; }
  209.   if (port->flags & p_trans) if (!isdcd())
  210.     { cmdtnc(); port->mode = idle; return true; }
  211.   return false;
  212. }
  213.  
  214. /*
  215.  *  Read the next input line from FWD.MB,
  216.  *  or from a file referenced from FWD.MB.
  217.  *  Return NULL if no more lines to read.
  218.  */
  219.  
  220. char *nxtin(p)
  221. char *p;
  222. {
  223.   register char *st, i;
  224.  
  225.   while (deep >= 0)
  226.   {
  227.     i = 1;
  228.     if ((st = fgets(p, 80, ifl[deep])) is NULL)
  229.     {
  230.       fclose(ifl[deep]);
  231.       deep--;
  232.     }
  233.     else
  234.     {
  235.       if (*p isnt '@') return st;
  236.       if (fopts & fw_pass) return st;
  237.       if (*(p+1) is ' ')
  238.       {
  239.         if (!chktime()) return st;
  240.         i = 6;
  241.       }
  242.       if (deep < (deepmax - 1))
  243.       {
  244.         strupr(p);
  245.         remnl(p);
  246.         deep++;
  247.         if ((ifl[deep] = fopen(p + i, "r")) is NULL) deep--;
  248.       }
  249.     }
  250.   }
  251.   return NULL;
  252. }
  253.  
  254. /*
  255.  *  Do some DOS commands.
  256.  */
  257.  
  258.  
  259. dofdos()
  260. {
  261.   register PORTS *p;
  262.  
  263.   if ((p = findport(cport->opt2)) is NULL) { passlst(); return; }
  264.   if (strlen(cport->fld[0]) > 3) if (!chktime()) { passlst(); return; }
  265.   if (fopts)
  266.   if (!((fopts & fw_one) and (match(fcall, cport->fld[1]))))
  267.   { passlst(); return; }
  268.  
  269. /*
  270.  *  Just in case, flush whatever might be currently open.
  271.  */
  272.  
  273.   clnuser();
  274.   clnmsg();
  275.   clnlog();
  276.  
  277.   while (nxtin(cport->line) isnt NULL)
  278.   {
  279.     if (iseof(cport->line)) return;
  280.     remnl(cport->line);
  281.     printf("\nRunning: %s\n", cport->line);
  282.     if (system(cport->line)) perror("Error");
  283.   }
  284. }
  285.  
  286. /*
  287.  *  The entry to fowarding.
  288.  */
  289.  
  290. fwd()
  291. {
  292.   register PORTS *p;
  293.  
  294. /*
  295.  *  If no fwd.mb file, then do nothing.
  296.  */
  297.  
  298.   deep = 0;
  299.   if ((ifl[deep] = fopen(fwdfile, "r")) is NULL) return;
  300.  
  301.   bldfwd();
  302.  
  303.   script = tmp->scr;
  304.   *script = '\0';
  305.  
  306.   while(nxtin(cport->line) isnt NULL)
  307.   {
  308.     bidok = false;
  309.     hidok = false;
  310.     ioport(cport);
  311.     strupr(cport->line);
  312.     parse();
  313.     fwdtyp = cport->opt1;
  314.     switch (fwdtyp)
  315.     {
  316.       case 'E':
  317.         passlst();
  318.         script = tmp->scr;
  319.         *script = '\0';
  320.         break;
  321.       case 'D':
  322.       case 'F':
  323.       case 'G':
  324.       case 'H':
  325.         if ((p = chkfwd()) isnt NULL)
  326.         {
  327.           fopts clrbit fw_tried;
  328. /*
  329.  *  Save tail of list header for logging.
  330.  */
  331.           strcpy(path, cport->line + 6);
  332.           remnl(path);
  333.           script = tmp->scr;
  334.           if (!*script)
  335.           {
  336.             *script = 'C';
  337.             strcpy(script + 1, cport->line + 6);
  338.             *(script + strlen(script) + 1) = '\0';
  339.           }
  340.           dofwd(p);
  341.           dorev(p);
  342.           distnc();
  343.           p->mode = idle;
  344.           ioport(cport);
  345.         }
  346.         script = tmp->scr;
  347.         *script = '\0';
  348.         break;
  349.  
  350.       case 'P':
  351.         dopar();
  352.         break;
  353.  
  354.       case '!':
  355.         dofdos();
  356.         break;
  357.  
  358.       case 'C':
  359.       case 'R':
  360.       case 'S':
  361.         strcpy(script, cport->line);
  362.         script += (strlen(cport->line) + 1);
  363.         *script = '\0';
  364.         break;
  365.  
  366.       default:  break;
  367.     }
  368.   }
  369.  
  370. /*
  371.  *  Put us back on the port we were on when we got here.
  372.  */
  373.  
  374.   ioport(cport);
  375.   bidok = false;
  376.   hidok = false;
  377. }
  378.  
  379. /*
  380.  *  A and AI commands.
  381.  */
  382.  
  383. all_fwd()
  384. {
  385.   byte pflg;
  386.   port->opt1 = 'X';
  387.   putcomd( port->opt1, port->opt2 );
  388.  
  389.   pflg = getp_flag();
  390.   putc_flag (pflg);
  391.   port->mode = logout;
  392. }
  393.  
  394. /*
  395.  *  X and XI commands.
  396.  */
  397.  
  398. sfwd()
  399. {
  400.   register PORTS *p;
  401.  
  402. /*
  403.  *  If remote sysop did the command, just remember it for later.
  404.  */
  405.  
  406.   if (port->mode & sysop) { savecmd(); return; }
  407.  
  408. /*
  409.  *  Set up parameters for fwd()
  410.  */
  411.  
  412.   fopts = fw_forced;
  413.   for (p = porthd; p isnt NULL; p = p->next)
  414.   {
  415.     p->ec = p->ecuser;
  416.     p->flags setbit p_dofwd;
  417.   }
  418.  
  419.   if (cport->flds is 2)
  420.   {
  421.     fopts setbit fw_one;
  422.     strncpy (fcall, cport->fld[1], ln_callp);
  423.   }
  424.  
  425.   if (cport->opt2 is 'I') fopts setbit fw_anytime;
  426.  
  427.   fwd();
  428.  
  429. /*
  430.  *  Reset the port flags.
  431.  */
  432.  
  433.   for (p = porthd; p isnt NULL; p = p->next)
  434.   {
  435.     p->ec = p->ecmon;
  436.     p->flags clrbit p_dofwd;
  437.   }
  438. }
  439.  
  440. /*
  441.  *  Automatic forwarding.
  442.  *  Called once each minute when the MailBox is idle.
  443.  */
  444.  
  445. afwd(curmin)
  446. int curmin;
  447. {
  448.   register PORTS *p;
  449.   register short anyfwd;
  450.  
  451. /*
  452.  *  Mark the ports that should forward at this minute.
  453.  */
  454.  
  455.   fopts = 0;
  456.   anyfwd = false;
  457.   for (p = porthd; p isnt NULL; p = p->next) if (p->fwdmin is curmin)
  458.   {
  459.     p->flags setbit p_dofwd;
  460.     p->ec = p->ecuser;
  461.     anyfwd = true;
  462.   }
  463.  
  464. /*
  465.  *  If any ports forward at this minute, do the forwarding.
  466.  */
  467.  
  468.   if (anyfwd)
  469.   {
  470.     setbusy();
  471.     alloff();   /* Turn off connects and monitoring */
  472.     if (s_flag & s_dv) begin_lock();
  473.     readmsg();
  474.     readusr();
  475.  
  476. /*
  477.  *  Write out mon and calls heard files
  478.  */
  479.     clsmon();
  480.  
  481. /*
  482.  *  Once a day, do wp and stale
  483.  */
  484.     if (!matchn(ufhs->wpdate, l_date, ln_date))
  485.     {
  486.       port->opt1 = '\0';
  487.       port->flds = 1;
  488.       dwuser();
  489.       stale();
  490.       strncpy(ufhs->wpdate, l_date, ln_date);
  491.       write_rec(ufl, 0, (char *)ufhs);
  492.     }
  493.     if (s_flag & s_dv) end_lock();
  494.  
  495. /*
  496.  * Check and see if the mailfile should be compressed
  497.  */
  498.     if (s_param & s_unt)
  499.     if (!matchn(mfhs->date, l_date, ln_date))
  500.     if (unt_hr <= (10 *(l_time[0] - '0') + (l_time[1] - '0')))
  501.     {
  502.       port->opt2 = 'A';
  503.       setunt();
  504.     }
  505.  
  506.     fwd();
  507.     clnlog();
  508.     setfwd();
  509.     clsmsg();
  510.     clsusr();
  511.     allon();    /* Turn on monitoring and connects */
  512.     clrbusy();
  513.   }
  514.  
  515. /*
  516.  *  Reset the port flags.
  517.  */
  518.  
  519.   for (p = porthd; p isnt NULL; p = p->next)
  520.   {
  521.     p->ec = p->ecmon;
  522.     p->flags clrbit p_dofwd;
  523.   }
  524. }
  525.  
  526. /*
  527.  *  Reverse forwarding.
  528.  *  Accept messages from the remote MailBox after forwarding to it.
  529.  */
  530.  
  531. dorev(p)
  532. PORTS *p;
  533. {
  534.   ioport(p);
  535.  
  536.   if (fwdtyp is 'G') return;
  537.   if (fwdtyp is 'D') return;
  538.  
  539.   if (p->mode & idle)
  540.   {
  541.     if (fwdtyp is 'F') return;
  542.     if (fwdtyp is 'H') if (fopts & fw_tried) return;
  543.     cmb();
  544.     if (p->mode & idle) return;
  545.   }
  546.  
  547.   pcall(fcall, path + 2);
  548.   rduser(fcall, p->user);
  549.   log ('M', 'F', 'R', path);  /* Log start of reverse forward */
  550.  
  551.   if (p->tmode)
  552.   {
  553.      cmdtnc();
  554.      trantnc();
  555.   }
  556.  
  557.   while(true)
  558.   {
  559.     outstr("F>\n");
  560.     getln();
  561.     if (p->mode & idle) return;
  562.     parse();
  563.  
  564.     if (p->opt1 isnt 'S') return;
  565.     {
  566.       sndmsg();
  567.       if (p->mode & gone) return;
  568.       addfwd();
  569.     }
  570.   }
  571. }
  572.  
  573. /*
  574.  *  F> command: do reverse forward to logged user.
  575.  */
  576.  
  577. fwdcmd()
  578. {
  579.   register PORTS *p;
  580.   register short ok;
  581.  
  582. /*
  583.  *  If no fwd.mb file, then do nothing.
  584.  */
  585.  
  586.   p = port;
  587.   deep = 0;
  588.   if ((ifl[deep] = fopen(fwdfile, "r")) is NULL) { p->mode = forced; return; }
  589.  
  590.   ioport(cport);
  591.  
  592. /*
  593.  *  Find the users E, F, G, or H list in the fwd.mb file.
  594.  */
  595.  
  596.   ok = false;
  597.   while(!ok and (nxtin(cport->line) isnt NULL))
  598.   {
  599.     strupr(cport->line);
  600.     parse();
  601.     fwdtyp = cport->opt1;
  602.  
  603.     switch(fwdtyp)
  604.     {
  605.       case 'D' :
  606.       case 'E' :
  607.       case 'F' :
  608.       case 'G' :
  609.       case 'H' :
  610.         pcall(fcall, cport->fld[1]);
  611.         ok = matchn(fcall, p->user->call, ln_call);
  612.  
  613.         if (!ok) passlst();
  614.         break;
  615.  
  616.       case '!' :
  617.       case 'P' :
  618.         passlst();
  619.         break;
  620.  
  621.       default  : ;   /* 'C', 'R', 'S' */
  622.     }
  623.   }
  624.  
  625.   ioport(p);
  626.  
  627.   if (ok)
  628.   {
  629.     log ('M', 'F', 'S', nullstr);      /* Log start of forwarding */
  630.     bldfwd();
  631.     remnl(cport->line);
  632.     strcpy( path, cport->line+6 );
  633.     dofwd(p);
  634.     log ('M', 'F', 'E', nullstr);      /* Log end of forwarding */
  635.   }
  636.  
  637.   while (deep >= 0) { fclose(ifl[deep]); deep--; }
  638.   if(p->mode is idle) return;
  639.   outstr("*** Done.\n");
  640. }
  641.  
  642. /*
  643.  *  Pass a sublist in the forwarding file.
  644.  */
  645.  
  646. passlst()
  647. {
  648.   fopts setbit fw_pass;
  649.   while (true)
  650.   {
  651.     if (nxtin(cport->line) is NULL) {fopts clrbit fw_pass; return;}
  652.     if (iseof(cport->line)) {fopts clrbit fw_pass; return;}
  653.   }
  654. }
  655.  
  656. /*
  657.  *  Set tnc parameters.
  658.  */
  659.  
  660. dopar()
  661. {
  662.   register PORTS *p;
  663.  
  664.   if ((p = findport(cport->opt2)) is NULL) { passlst(); return; }
  665.  
  666.   if (strlen(cport->fld[0]) > 3) if (!chktime()) { passlst(); return; }
  667.  
  668.   ioport(p);
  669.   while (nxtin(cport->line) isnt NULL)
  670.   {
  671.     if (iseof(cport->line)) { ioport(cport); return; }
  672.     onetnc(cport->line);
  673.   }
  674.   ioport(cport);
  675. }
  676.  
  677. /*
  678.  *  Get a line from the current port.
  679.  *  Handle disconnect, timeout, and ^F.
  680.  */
  681.  
  682. getln()
  683. {
  684.   while (!getdat());
  685.   if (port->mode & forced) fopts setbit fw_abort;
  686.   if (port->mode & gone) { distnc(); port->mode = idle; }
  687. }
  688.  
  689. /*
  690.  *  Eat the remote MailBox prompt.
  691.  */
  692.  
  693. eat()
  694. {
  695.   register char c;
  696.  
  697.   if (fwdtyp is 'D') c = ':'; else c = '>';
  698.   while(true) {
  699.     getln();
  700.     if (!(port->mode & remote)) return;
  701.     if (port->line[0] is '[') isbid();
  702.     if ((port->mode & remote) and (port->line[strlen(port->line) - 2] is c)) {
  703.       return;
  704.     }
  705.   } 
  706. }
  707.  
  708. /*
  709.  *  Connect to a remote Mailox.
  710.  *  Port mode idle at entry.
  711.  *  On return, port mode is remote if the connect worked, else idle.
  712.  */
  713.  
  714. cmb()
  715. {
  716.   port->flags setbit p_dotmr;
  717.   port->mode = remote;
  718.  
  719. /*
  720.  *  Execute the connect script.
  721.  */
  722.  
  723.   while(*script)
  724.   {
  725.     switch (*script++)
  726.     {
  727.       case 'C' :
  728.         contnc(script);
  729.         if (port->mode & idle) return;
  730.         if (port->dev is p_tnc) do
  731.         {
  732.           getln();
  733.           if (port->mode & idle) return;
  734.         }
  735.         while (!iscon(port->line));
  736.         break;
  737.  
  738.       case 'S' :
  739.         outstr(script);
  740.         break;
  741.  
  742.       case 'R' :
  743.         getln();
  744.         if (port->mode & idle) return;
  745.         strupr(port->line);
  746.         if (*script isnt '!')
  747.         if (!search(port->line, script, strlen(script)-1))
  748.           { distnc(); port->mode = idle; return; }
  749.         break;
  750.  
  751.        default: ;
  752.     }
  753.     while(*script++);  /* Move to next script line */
  754.   }
  755.  
  756. /*
  757.  *  In theory, now connected to MailBox. Eat login messge.
  758.  */
  759.  
  760.   eat();
  761.   if (!(port->mode & remote)) return;
  762.   if (bidok) {
  763.     outstr("[CBBS-6.0-H$]\n");
  764.     eat();
  765.   }
  766. }
  767.  
  768. /*
  769.  *  Forward whatever messages go to this MailBox.
  770.  */
  771.  
  772. dofwd(p)
  773. PORTS *p;
  774. {
  775.   register char *st;
  776.  
  777.   st = nxtin(cport->line);
  778.   while (!iseof(cport->line) and (st isnt NULL))
  779.   {
  780.     ioport(cport);
  781.     parse();
  782.     ioport(p);
  783.     pcall (tcall, cport->fld[0]);
  784.  
  785.     if (findfwd(tcall, bfwd, bfwdn))
  786.     {
  787.       fmsg();
  788.       if (fopts & fw_tried) if (p->mode & idle)
  789.       {
  790.          p->mmhs->stat clrbit m_busy;
  791.          wt_mmhs();
  792.          passlst();
  793.          return;
  794.       }
  795.     }
  796.  
  797.     st = nxtin(cport->line);
  798.   }
  799. }
  800.  
  801. /*
  802.  *  Send the message text.
  803.  */
  804.  
  805. xmtmsg()
  806. {
  807.   register FILE *fl;
  808.  
  809.   sprintf(port->line, "%s%u", msgdir, port->mmhs->number);
  810.   if ((fl = fopen(port->line, "r")) is NULL) nofile(port->line); else
  811.   {
  812.     fseek(fl, (long)RECSIZE, 0);
  813.     while(fgets(tmp->scr, scrmax, fl) isnt NULL)
  814.     {
  815.       if (chkdis()) { fclose(fl); return false; }
  816.       outstr(tmp->scr);
  817.     }
  818.     fclose (fl);
  819.   }
  820.   if (fwdtyp is 'D')
  821.   {
  822.     outstr(".\n");
  823.     outstr("y\n");
  824.   }
  825.   else
  826.   {
  827.     outchar (cpmeof);
  828.     outchar ('\n');
  829.   }
  830.   return true;
  831. }
  832.  
  833. /*
  834.  *  Forward all messages TO or AT tcall
  835.  *  to the MailBox we are connected to.
  836.  */
  837.  
  838. fmsg()
  839. {
  840.   char *a, *b, *c;
  841.   char hcall[6];
  842.   register PORTS *p;
  843.   register word h;
  844.   register short i, ok, kill, extnr, kok, hasit;
  845.  
  846.   hasit = true;   /* just initialize it to something */
  847.  
  848.   p = port;
  849.   for (h = mfhs->last; h; h--)
  850.   {
  851.     if (s_flag & s_dv) begin_lock();
  852.     read_rec(mfl, h, (char *)p->mmhs);
  853.  
  854.     ok = (!(p->mmhs->stat & (m_kill | m_read | m_fwd | m_hold | m_busy)));
  855. /*
  856.  *  Decide whether to forward this one.
  857.  */
  858.     if (ok)
  859.     {
  860.       if (p->mmhs->ext is 1)
  861.       {
  862.         ok = false;
  863.         for (i = 0; !ok and (i < p->mmhs->count); i++) if (p->mmhs->flag[i])
  864.           if (wcm(tcall, p->mmhs->call[i])) { ok = true; extnr = i; }
  865.       }
  866.       else if (*p->mmhs->bbs isnt ' ')
  867.       {
  868.         ok = wcm(tcall, p->mmhs->bbs);
  869.         if (!ok) if (p->mmhs->ext is 2)
  870.         {
  871.           c = p->mmhs->call[0];
  872.           while(!ok and ((c=strchr(c, '.')) isnt NULL))
  873.           {
  874.             c++;
  875.             fill(hcall, ' ', ln_call);
  876.             pcall(hcall, c);
  877.             ok = wcm(tcall, hcall);
  878.           }
  879.         }
  880.       }
  881.       else ok = wcm(tcall, p->mmhs->to);
  882.     }
  883.  
  884.     if (ok)
  885.     {
  886.       p->mmhs->stat setbit m_busy;
  887.       wt_mmhs();
  888.     }
  889.     if (s_flag & s_dv) end_lock();
  890.  
  891. /*
  892.  *  If we DO forward this one, forward this one.
  893.  */
  894.     if (ok)
  895.     {
  896.       if (fopts & fw_tiout) { wait (p->ftime); fopts clrbit fw_tiout; }
  897.       fopts setbit fw_tried;
  898.       if (p->mode & idle) cmb();
  899.       if (p->mode & idle) return;
  900.  
  901.       if (fwdtyp is 'D') prtx("mail $G\n");
  902.  
  903.       if (*p->mmhs->bbs is ' ') prtx("S$B $G < $P");
  904.       else if((hidok)and(p->mmhs->ext is 2)) prtx("S$B $G @ $h < $P");
  905.       else prtx("S$B $G @ $A < $P");
  906.  
  907.       if (bidok) if (*p->mmhs->bid isnt ' ') {
  908.         outstr(" $");
  909.         a = p->line;
  910.         b = p->mmhs->bid;
  911.         unbl(a, b, ln_bid);
  912.         outstr(p->line);
  913.       }
  914.       outchar('\n');
  915.       getln(); if (p->mode & idle) return;
  916.       if (bidok)
  917.       {
  918.         if(*p->line < ' ') { getln(); if(p->mode & idle) return; }
  919.         switch(*p->line)
  920.         {
  921.           case 'O': hasit = false;
  922.                     outstr(p->mmhs->title);
  923.                     outchar('\n'); break;
  924.           case 'N': hasit = true; break;
  925.           default : p->mmhs->stat clrbit m_busy;
  926.                     wt_mmhs();
  927.                     return;
  928.         }
  929.       }
  930.       else
  931.       {
  932.         hasit = false;        /* you'll want to send msg */
  933.         outstr(p->mmhs->title); outchar('\n');
  934.         if (fwdtyp isnt 'D')
  935.         {
  936.           getln(); if (p->mode & idle) return;
  937.         }
  938.       }
  939.       if (!hasit)
  940.       {
  941.         curtim();
  942.         if (port->dev is p_tnc) prtx(mm[4]);
  943.         if (!xmtmsg()) { fopts setbit fw_tiout; return;}
  944.       }
  945.       eat(); if (p->mode & idle){ fopts setbit fw_tiout; return; }
  946. /*
  947.  *  The message actually forwarded.
  948.  *  Kill it, mark it, or whatever.
  949.  */
  950.       sprintf(p->line, "%u %s", p->mmhs->number, path);
  951.       log ('M', 'F', ' ', p->line);
  952.  
  953.       kill = false;
  954.       kok = false;
  955. /*
  956.  *  If cc: list exists, mark this call as forwarded.
  957.  */
  958.       if (p->mmhs->ext is 1)
  959.       {
  960.         p->mmhs->flag[extnr] = false;
  961.         for (i = 0; i < p->mmhs->count; i++) if (p->mmhs->flag[i]) kok = true;
  962.       }
  963.  
  964.       if (!kok)
  965.       {
  966.         if ((p->mmhs->type is 'F') or (p->mmhs->type is 'B'))
  967.         kill = s_param & s_fkill;
  968.         else kill = s_param & s_kill;
  969.       }
  970.  
  971.       if (kill) p->mmhs->stat setbit m_kill;
  972.       else
  973.         if (!kok) p->mmhs->stat setbit m_fwd;
  974.       p->mmhs->stat clrbit m_busy;
  975.       write_rec(mfl, p->mmhs->rn, (char *)p->mmhs);
  976.       makehdr2();
  977.     }
  978.   }
  979. }
  980.